home *** CD-ROM | disk | FTP | other *** search
- #include <fp.h>
-
- #include "kSanSimulationPrivate.h"
- #include "OHApplicationPublic.h"
-
- short resizeBoxHandle (kSanSimulation *sim, long x, long y, long z) ;
- short resizeBoxHandle (kSanSimulation *sim, long x, long y, long z)
- { // slots is the number of particles per box we allocate in memory
- short err = noErr;
- long i;
- box *boxes;
- long oldNumberOfBoxes = sim->howManyBoxes;
- sim->boxDim.a = x;
- sim->boxDim.b = y;
- #ifndef __2DVectors__
- sim->boxDim.c = z;
- #endif
- sim->howManyBoxes = x * y * z;
-
- if (sim->howManyBoxes > oldNumberOfBoxes)
- {
- err = LCHSetHandleSize(&sim->boxArrayLCH,(sizeof(box) * (sim->howManyBoxes +2L)));
- if (!err)
- {
-
- boxes = simLockBoxes(sim);
- for (i = oldNumberOfBoxes+2; i < sim->howManyBoxes+2; ++i)
- {
- initializeList (&(boxes[i].boxPartList));
- }
- simReleaseBoxes(sim);
- }
- else
- {
- sim->howManyBoxes = oldNumberOfBoxes;
- }
- }
- else
- {
- boxes = simLockBoxes(sim);
- for (i = sim->howManyBoxes+2 ; i < oldNumberOfBoxes+2; ++i)
- {
- disposeList (&(boxes[i].boxPartList));
- }
- simReleaseBoxes(sim);
- err = LCHSetHandleSize(&sim->boxArrayLCH,(sizeof(box) * (sim->howManyBoxes +2L)));
- }
- return (err);
- }
- short initBoxes (kSanSimulation *sim)
- { // slots is the number of particles per box we allocate in memory
- short err = noErr;
- long maxx,maxy,maxz;
- long x[3],y[3],z[3];
- long i,j,k,counter;
- long xcount, ycount, zcount;
- long howManyNBs;
- long thisBoxLabel;
- long thatBoxLabel;
- Handle tempPadding = nilPointer;
- box * thisBox;
- box * boxes;
- float dummy;
-
- #ifdef __2DVectors__
- #pragma unused (zcount)
- #endif
-
- dummy = sim->simCell.cellDim.a/(sim->outerCutoff + 1.0); // implicit type conversion
- maxx = dummy;
- dummy = sim->simCell.cellDim.b/(sim->outerCutoff + 1.0);
- maxy = dummy;
-
- #ifndef __2DVectors__
- dummy = sim->simCell.cellDim.c/(sim->outerCutoff + 1.0);
- maxz = dummy;
- #else
- maxz = 1;
- #endif
-
- if (!(maxx>0)) maxx = 1;
- if (!(maxy>0)) maxy = 1;
- if (!(maxz>0)) maxz = 1;
-
- tempPadding = NewHandle(100000L);
-
- if (!err) err = resizeBoxHandle(sim, maxx, maxy, maxz);
-
- while ((err) && (sim->howManyBoxes > 9))
- {
- if (maxx > 3) maxx = maxx - 1;
- if (maxy > 3) maxy = maxy - 1;
- #ifndef __2DVectors__
- if (maxz > 3) maxz = maxz - 1;
- #endif
- err = resizeBoxHandle(sim, maxx, maxy, maxz);
- }
- if (err)
- {
- doAlert("\pMemory error in box allocation");
- sim->flags.error = kSanErrBoxMemory;
- }
- else
- {
- boxes = simLockBoxes(sim);
- // initialize the which contains hyperspace particles
- thisBox = &boxes[sim->howManyBoxes + 1];
- thisBox->label = sim->howManyBoxes + 1;
- thisBox->Xindex = -1;
- thisBox->Yindex = -1;
- thisBox->Zindex = -1;
- for (howManyNBs = 0;howManyNBs<NUMNEIGHBORINGBOXES;++howManyNBs)
- { // initialize the hyperspace box (particles not in cell)
- thisBox->neighboringBoxes[howManyNBs] = 0L; // setting all the neighbor boxes to 0 means that
- // particles in box zero only interact with particles in box 0 :: i.e. no particles
- // particles must be initialized to box (sim->howManyBoxes + 1);
- }
- // initialize the box which never contains anything
- counter = 0;
- thisBox = boxes;
- thisBox->label = counter;
- thisBox->Xindex = -1;
- thisBox->Yindex = -1;
- thisBox->Zindex = -1;
- for (howManyNBs = 0;howManyNBs<NUMNEIGHBORINGBOXES;++howManyNBs)
- { // initialize the zero box (not in cell)
- thisBox->neighboringBoxes[howManyNBs] = 0L; // setting all the neighbor boxes to 0 means that
- // particles in box zero only interact with particles in box -1 :: i.e. no particles
- // particles must be initialized to box 0;
- }
- ++ counter;
- // label neighbors of all other boxes
- for (i=0;i<maxx;++i)
- {
- if (i==0) x[0] = maxx-1;
- else x[0] = i-1;
- x[1] = i;
- if (i==(maxx-1)) x[2] = 0;
- else x[2] = i+1;
- for (j=0;j<maxy;++j)
- {
- if (j==0) y[0] = maxy-1;
- else y[0] = j-1;
- y[1] = j;
- if (j==(maxy-1)) y[2] = 0;
- else y[2] = j+1;
- for (k=0;k<maxz;++k)
- {
- thisBox = &boxes[counter];
- //thisBox = (boxes + ((counter) * (sim->boxRecordSize)));
- thisBox->label = counter;
- thisBox->Xindex = i;
- thisBox->Yindex = j;
- thisBox->Zindex = k;
-
- if (k==0) z[0] = maxz-1;
- else z[0] = k-1;
- z[1] = k;
- if (k==(maxz-1)) z[2] = 0;
- else z[2] = k+1;
-
- thisBoxLabel = maxz*maxy*i + maxz*j + k + 1L;
- if (thisBoxLabel != counter) doAlert("\pBox counting error. Unknown cause. Exiting");
- howManyNBs = 0;
- for (xcount=0;xcount<3;++xcount)
- {
- for (ycount=0;ycount<3;++ycount)
- {
- #ifndef __2DVectors__
- for (zcount=0;zcount<3;++zcount)
- {
- thatBoxLabel = maxz*maxy*x[xcount] + maxz*y[ycount] + z[zcount] + 1L; // include same box
- thisBox->neighboringBoxes[howManyNBs] = thatBoxLabel;
- ++howManyNBs;
- }
- #else
- thatBoxLabel = maxy*x[xcount] + y[ycount] + 1L; // include same box
- thisBox->neighboringBoxes[howManyNBs] = thatBoxLabel;
- ++howManyNBs;
- #endif
- }
- }
- ++counter;
- }
- }
- }
- for (thisBoxLabel=0; thisBoxLabel <= sim->howManyBoxes + 1L ; ++thisBoxLabel)
- {
- thisBox = &boxes[thisBoxLabel];
- //thisBox = (boxes + (thisBoxLabel * (sim->boxRecordSize)));
- thisBox->boxPartList.howManyItems = 0; // clear box contents
- }
- simReleaseBoxes(sim);
- OHDisposeHandle(&tempPadding);
- sim->counters.neighbor = sim->countThreshholds.neighbor + 1L; // force a complete get neighbors
- }
-
- return (err);
- }
- short setBoxForPartList(kSanSimulation *sim, OHList *partList)
- {
- short err = noErr;
- particle *unusedBasePart;
- box * unusedBoxes;
- // these calls should speed up the function by preventing toolbox calls to
- // LockHandle and UnlockHandle inside sim->setBoxForPart()
- unusedBasePart = simLockParts(sim);
- unusedBoxes = simLockBoxes(sim);
- // end unused stuff
-
- err = OHListEveryItemAsSecondArg( partList, sim->setBoxForPart, sim);
-
- simReleaseBoxes(sim);
- simReleaseParts(sim);
- return (err);
- }
-
- long determineBoxForPartTriclinic(kSanSimulation *sim,long partArrIndex)
- {
- short err = noErr;
- long whichBox;
- // particle * thisPart;
- particle * basePart;
- short whichX;
- short whichY;
- short whichZ;
- double XCutOff;
- double YCutOff;
- double ZCutOff;
- double inverseCellXDim;
- double inverseCellYDim;
- double inverseCellZDim;
- kSanVector adjPos;
-
- #ifdef __2DVectors__
- #pragma unused(whichZ)
- #pragma unused(ZCutOff)
- #pragma unused(inverseCellZDim)
- #endif
-
- basePart = simLockParts(sim);
- // thisPart = &(basePart[partArrIndex]);
-
- XCutOff = sim->simCell.cellDim.a *0.5;
- YCutOff = sim->simCell.cellDim.b *0.5;
- #ifndef __2DVectors__
- ZCutOff = sim->simCell.cellDim.c *0.5;
- #endif
- inverseCellXDim = sim->boxDim.a / (sim->simCell.cellDim.a + 0.01); // these small number give a little leeway
- inverseCellYDim = sim->boxDim.b / (sim->simCell.cellDim.b + 0.01);
- #ifndef __2DVectors__
- inverseCellZDim = sim->boxDim.c / (sim->simCell.cellDim.c + 0.01);
- #endif
- err = getAdjustedPositionWithWrap(&sim->simCell, &basePart->basePosition[partArrIndex], &adjPos);
-
- if (!err)
- {
- whichX = trunc((adjPos.a + XCutOff) * inverseCellXDim);
- whichY = trunc((adjPos.b + YCutOff) * inverseCellYDim);
- #ifndef __2DVectors__
- whichZ = trunc((adjPos.c + ZCutOff) * inverseCellZDim);
- whichBox = sim->boxDim.c*sim->boxDim.b*whichX + sim->boxDim.c*whichY + whichZ + 1;
- #else
- whichBox = sim->boxDim.b*whichX + whichY + 1;
- #endif
- if (whichBox > sim->howManyBoxes) whichBox = -1;
- }
- else
- {
- whichBox = -1;
- }
- simReleaseParts(sim);
-
- return (whichBox);
- }
-
- short setBoxForPartTriclinic(kSanSimulation *sim,long partArrIndex)
- {
- short err = noErr;
- box * boxes;
- particle *basePart;
- long whichBox;
- long oldBox;
-
- basePart = simLockParts(sim);
- boxes = simLockBoxes(sim);
- whichBox = determineBoxForPartTriclinic(sim, partArrIndex);
-
- oldBox = BPNthBoxIndex(basePart, partArrIndex);
- if ((oldBox != whichBox) && (oldBox != -1))
- {
- removeItem(&boxes[oldBox].boxPartList, partArrIndex);
- err = addPartToBox(sim, basePart, partArrIndex, whichBox, boxes);
- switch (err)
- {
- case noErr:
- default:
- break;
- case kSanErrUnallocatedBox:
- doAlert("\p unallocated neighbor box error. Please report this error and how you arrived here!");
- break;
- }
- }
- simReleaseParts(sim);
- simReleaseBoxes(sim);
- return (err);
- }
- long determineBoxForPartOrthorhombic(kSanSimulation *sim,long partArrIndex)
- {
- long err = noErr;
- long whichBox;
- //particle * thisPart;
- kSanVector *thisPos;
- particle * basePart;
- short whichX;
- short whichY;
- short whichZ;
- char nanFlag = false;
- char outOfBox = false;
- double XCutOff;
- double YCutOff;
- double ZCutOff;
- double inverseCellXDim;
- double inverseCellYDim;
- double inverseCellZDim;
-
- #ifdef __2DVectors__
- #pragma unused(whichZ)
- #pragma unused(ZCutOff)
- #pragma unused(inverseCellZDim)
- #endif
-
- basePart = simLockParts(sim);
- //thisPart = &(basePart[partArrIndex]);
- thisPos = &basePart->basePosition[partArrIndex];
- XCutOff = sim->simCell.cellDim.a *0.5;
- YCutOff = sim->simCell.cellDim.b *0.5;
-
- #ifndef __2DVectors__
- ZCutOff = sim->simCell.cellDim.c *0.5;
- #endif
-
- if ((thisPos->a <= XCutOff) && (thisPos->a >= ( -XCutOff))) {}
- else
- {
- if (thisPos->a > XCutOff)
- {
- thisPos->a -= sim->simCell.cellDim.a;
- if(thisPos->a > XCutOff) outOfBox = true;
- }
- else if (thisPos->a < (-XCutOff))
- {
- thisPos->a += sim->simCell.cellDim.a;
- if (thisPos->a < (-XCutOff)) outOfBox = true;
- }
- else outOfBox = true;
- }
-
- if ((thisPos->b <= YCutOff) && (thisPos->b >= ( -YCutOff))) {}
- else
- {
- if (thisPos->b > YCutOff)
- {
- thisPos->b -= sim->simCell.cellDim.b;
- if(thisPos->b > YCutOff) outOfBox = true;
- }
- else if (thisPos->b < (-YCutOff))
- {
- thisPos->b += sim->simCell.cellDim.b;
- if (thisPos->b < (-YCutOff)) outOfBox = true;
- }
- else outOfBox = true;
- }
-
- #ifndef __2DVectors__
- if ((thisPos->c <= ZCutOff) && (thisPos->c >= ( -ZCutOff))) {}
- else
- {
- if (thisPos->c > ZCutOff)
- {
- thisPos->c -= sim->simCell.cellDim.c;
- if(thisPos->c > ZCutOff) outOfBox = true;
- }
- else if (thisPos->c < (-ZCutOff))
- {
- thisPos->c += sim->simCell.cellDim.c;
- if (thisPos->c < (-ZCutOff)) outOfBox = true;
- }
- else outOfBox = true;
- }
- #endif
-
- if (!outOfBox)
- {
- inverseCellXDim = (sim->boxDim.a - 0.001) * sim->simCell.invCellDim.a ; // these small number give a little leeway
- inverseCellYDim = (sim->boxDim.b - 0.001) * sim->simCell.invCellDim.b ; // these small number give a little leeway
- #ifndef __2DVectors__
- inverseCellZDim = (sim->boxDim.c - 0.001) * sim->simCell.invCellDim.c ; // these small number give a little leeway
- #endif
-
- whichX = trunc((thisPos->a + XCutOff) * inverseCellXDim);
- whichY = trunc((thisPos->b + YCutOff) * inverseCellYDim);
- #ifndef __2DVectors__
- whichZ = trunc((thisPos->c + ZCutOff) * inverseCellZDim);
- whichBox = sim->boxDim.c*sim->boxDim.b*whichX + sim->boxDim.c*whichY + whichZ + 1;
- #else
- whichBox = sim->boxDim.b*whichX + whichY + 1;
- #endif
- if ((whichBox < 0) || (whichBox > sim->howManyBoxes)) whichBox = -1;
- }
- else whichBox = -1;
-
- simReleaseParts(sim);
- return (whichBox);
- }
-
- short setBoxForPartOrthorhombic(kSanSimulation *sim,long partArrIndex)
- {
- long err = noErr;
- box * boxes;
- long oldBox;
- long whichBox;
- particle *basePart;
-
-
- basePart = simLockParts(sim);
- boxes = simLockBoxes(sim);
-
- whichBox = determineBoxForPartOrthorhombic(sim, partArrIndex);
-
- oldBox = BPNthBoxIndex(basePart, partArrIndex);
- if ((oldBox != whichBox) && (oldBox != -1))
- {
- removeItem(&boxes[oldBox].boxPartList, partArrIndex);
- err = addPartToBox(sim, basePart, partArrIndex, whichBox, boxes);
- switch (err)
- {
- case noErr:
- break;
- default:
- case kSanErrUnallocatedBox:
- OHSystemBeep();
- break;
- }
- }
- simReleaseParts(sim);
- simReleaseBoxes(sim);
- return (err);
- }
-